extern crate winapi;

use winapi::um::psapi::{EnumProcesses, GetProcessImageFileNameW};
use winapi::um::winnt::{PROCESS_QUERY_INFORMATION, PROCESS_VM_READ};
use winapi::um::processthreadsapi::OpenProcess;
use winapi::um::handleapi::CloseHandle;
use crate::model::Process;

#[tauri::command]
pub fn enum_processes() -> Result<Vec<Process>, String> {
    const MAX_PROCESS: usize = 1024;
    let mut processes: [u32; MAX_PROCESS] = [0; MAX_PROCESS];
    let mut bytes_returned: u32 = 0;
    let mut process_vector: Vec<Process> = Vec::new();

    unsafe {
        // 枚举进程
        if EnumProcesses(
            processes.as_mut_ptr(),
            (MAX_PROCESS as u32 * std::mem::size_of::<u32>() as u32) as u32,
            &mut bytes_returned,
        ) != 0
        {
            let number_of_processes = bytes_returned as usize / std::mem::size_of::<u32>();
            println!("Number of processes: {}", number_of_processes);
            
            // 输出每个进程的信息
            for i in 0..number_of_processes {
                let process_id = processes[i];
                let process_handle = OpenProcess(
                    PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                    0,
                    process_id,
                );

                if !process_handle.is_null() {
                    let mut buffer: [u16; 1024] = [0; 1024];
                    let size = (buffer.len() * std::mem::size_of::<u16>()) as u32;
                    if GetProcessImageFileNameW(process_handle, buffer.as_mut_ptr(), size) != 0 {
                        let image_file_name = String::from_utf16_lossy(&buffer[..(size as usize) / 2]);
                        let mut name: &str = &image_file_name;
                        name = name.trim_end_matches('\0');
                        let mut process = Process::default();
                        process.pid = process_id;
                        process.name = name.to_string();
                        process_vector.push(process);
                    }
                    CloseHandle(process_handle);
                }
            }
        } else {
            println!("Failed to enumerate processes");
        }
        Ok(process_vector)
    }
}